using System;
using L=Science.Physics.GeneralPhysics;

namespace Serway.Chapter10
{
	/// <summary>
	/// Example12: Angular Acceleration of a Wheel
	/// A wheel of radius R, mass M, and moment of inertia I 
	/// is mounted on a frictionless horizontal axle, as in Figure 10.20.
	/// A light cord wrapped around the wheel supports an object of mass m.
	/// Calculate the angular acceleration of the wheel, 
	/// the linear acceleration of the object, and tension in the cord.
	/// T = mg/(1+mR^2/I)
	/// a = g/(1 + I/mR^2)
	/// \alpha = g/(R + I/mR)
	/// </summary>
	public class Example12
	{
		public Example12()
		{
		}
		private string result;
		public string Result
		{
			get{return result;}
		}
		public void Compute()
		{
			L.Mass[] m = new L.Mass[1];
			L.TotalForce[] f = new L.TotalForce[1]; 			
			L.Acceleration[] a = new L.Acceleration[1];

			L.MomentOfInertia[] I = new L.MomentOfInertia[1];
			L.TotalTorque[] t = new L.TotalTorque[1];
			L.AngularAcceleration[] alpha = new L.AngularAcceleration[1];

			L.Position[] R = new L.Position[1];
				
			m[0]= new L.Mass();
			m[0].kg = 10.0;
				
			L.Force[] ff = new L.Force[2];
			ff[0] = new L.Force();  // tension
			ff[0].ZVariableQ = true;
			ff[1] = new L.Force();
			ff[1].Z = -m[0].kg*L.Constant.AccelerationOfGravity;
			f[0] = new L.TotalForce(ff);

			a[0] = new L.Acceleration();
			a[0].ZVariableQ = true; 

			I[0] = new L.MomentOfInertia();
			I[0].XX = 2500.0;

			L.Torque[] tau = new L.Torque[1];
			tau[0] = new L.Torque();
			tau[0].XVariableQ = true;
			t[0] = new L.TotalTorque(tau);			
			
			alpha[0] = new L.AngularAcceleration();
			alpha[0].XVariableQ = true; 

			R[0] = new L.Position();
			R[0].Y = -5.0;

			L.NewtonEquationInvolvingTorque.ConstraintFunctionToBeZero[] cf
				= new L.NewtonEquationInvolvingTorque.ConstraintFunctionToBeZero[2];
			cf[0] = new L.NewtonEquationInvolvingTorque.ConstraintFunctionToBeZero(Min1);
			cf[1] = new L.NewtonEquationInvolvingTorque.ConstraintFunctionToBeZero(Min2);  
			
			L.NewtonEquationInvolvingTorque eq 
				= new L.NewtonEquationInvolvingTorque(f,m,a,t,I,alpha,R);			
			eq.Constraint(cf);

			eq.Solve();
		
			result += Convert.ToString(a[0].Z)+"\r\n";
			result += Convert.ToString(-L.Constant.AccelerationOfGravity/(1.0 + I[0].XX/m[0].kg/R[0].Y/R[0].Y))+"\r\n";
	
			result += Convert.ToString(f[0].DecomposedForce[0].Z)+"\r\n";
			result += Convert.ToString(m[0].kg*L.Constant.AccelerationOfGravity/(1.0 + m[0].kg*R[0].Y*R[0].Y/I[0].XX))+"\r\n";
		}
		private double Min1(L.TotalForce[] f, L.Mass[] m, L.Acceleration[] a,
			L.TotalTorque[] tau, L.MomentOfInertia[] I, L.AngularAcceleration[] alpha, L.Position[] radius)
		{
			return f[0].DecomposedForce[0].Z*radius[0].Y + tau[0].DecomposedTorque[0].X;
		}
		private double Min2(L.TotalForce[] f, L.Mass[] m, L.Acceleration[] a,
			L.TotalTorque[] tau, L.MomentOfInertia[] I, L.AngularAcceleration[] alpha, L.Position[] radius)
		{
			return alpha[0].X - a[0].Z/radius[0].Y;
		}
	}
}
